package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.dto.SearchDataInConditionDTO;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.pojo.ItemDataPoJo;
import com.xbongbong.paas.pojo.dto.DetailLabelUpdateDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateBatchDTO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateBatchVO;
import com.xbongbong.paas.pojo.vo.SearchDataInConditionVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.domain.entity.LabelEntity;
import com.xbongbong.pro.domain.entity.LabelGroupEntity;
import com.xbongbong.pro.domain.entity.PersonLabelEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemLabelErrorCodeEnum;
import com.xbongbong.pro.label.pojo.GroupLabelTreePojo;
import com.xbongbong.pro.label.pojo.LabelPojo;
import com.xbongbong.pro.label.pojo.LabelSortPojo;
import com.xbongbong.pro.label.pojo.dto.AllLabelShowVO;
import com.xbongbong.pro.label.pojo.dto.LabelDeleteDTO;
import com.xbongbong.pro.label.pojo.dto.LabelListDTO;
import com.xbongbong.pro.label.pojo.dto.LabelRepeatDTO;
import com.xbongbong.pro.label.pojo.dto.LabelSaveDTO;
import com.xbongbong.pro.label.pojo.dto.LabelShowVO;
import com.xbongbong.pro.label.pojo.dto.LabelSortDTO;
import com.xbongbong.pro.label.pojo.dto.LabelTotalDeleteDTO;
import com.xbongbong.pro.label.pojo.dto.PersonLabelSaveDTO;
import com.xbongbong.pro.label.pojo.vo.LabelDeleteVO;
import com.xbongbong.pro.label.pojo.vo.LabelListVO;
import com.xbongbong.pro.label.pojo.vo.LabelRepeatVO;
import com.xbongbong.pro.label.pojo.vo.LabelSaveVO;
import com.xbongbong.pro.label.pojo.vo.LabelSortVO;
import com.xbongbong.pro.label.pojo.vo.LabelTotalDeleteVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.LabelGroupModel;
import com.xbongbong.saas.model.LabelModel;
import com.xbongbong.saas.model.PersonLabelModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.service.LabelGroupService;
import com.xbongbong.saas.service.LabelService;
import com.xbongbong.saas.service.ListBatchService;
import com.xbongbong.saas.service.PersonLabelService;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author guohui.zhang
 * @Title:
 * @date 2020/11/318:41
 */
@Service("labelService")
public class LabelServiceImpl implements LabelService {
    private static final Logger LOG = LoggerFactory.getLogger(LabelServiceImpl.class);

    @Resource
    private MongoLogHelp mongoLogHelp;

    @Resource
    private LabelModel labelModel;
    @Resource
    private LabelGroupModel labelGroupModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private LabelGroupService labelGroupService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PersonLabelModel personLabelModel;
    @Resource
    private ListBatchService listBatchService;
    @Resource
    private PersonLabelService personLabelService;
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private IndexTypeModel indexTypeModel;

    @Override
    public LabelListVO getLabelList(LabelListDTO labelListDTO) throws XbbException {
        String corpid = labelListDTO.getCorpid();
        Long groupId = labelListDTO.getGroupId();
        List<LabelPojo> labelPojos = new ArrayList<>();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("formId", labelListDTO.getFormId());
        param.put("del", DelEnum.NORMAL.getDel());
        Integer count = labelModel.getEntitysCount(param);
        if (Objects.equals(count, BasicConstant.ZERO) && !Objects.equals(labelListDTO.getGroupId(), 0L)){
            LabelEntity labelEntity = createDefaultLabel(labelListDTO);
            if (Objects.nonNull(labelEntity)) {
                LabelPojo labelPojo = new LabelPojo();
                BeanUtil.copyProperties(labelEntity, labelPojo);
                labelPojos.add(labelPojo);
            }
        } else {
            param.remove("formId");
            if (Objects.equals(BasicConstant.ZERO, labelListDTO.getEnable()) && !Objects.equals(BasicConstant.ZERO, labelListDTO.getGroupId())) {
                // 标签其他分组中处理
                param.put("groupId", groupId);
                param.put("orderByStr", " sort asc " );
            } else {
                // 标签回收站中处理
                param.put("formId", labelListDTO.getFormId());
                param.put("appId", labelListDTO.getAppId());
                param.put("orderByStr", "update_time desc" );
            }
            param.put("enable", labelListDTO.getEnable());
            List<LabelEntity> labelEntities = labelModel.findEntitys(param);
            // 为回收站储存labelId 与groupId 的关系
            Map<Long, Long> labelIdToGroupId = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> groupIds = new ArrayList<>();
            labelEntities.forEach(item -> {
                LabelPojo labelPojo = new LabelPojo();
                labelPojo.setColor(item.getColor());
                labelPojo.setName(item.getName());
                labelPojo.setFormId(item.getFormId());
                labelPojo.setId(item.getId());
                labelIdToGroupId.put(item.getId(), item.getGroupId());
                labelPojo.setSort(item.getSort());
                groupIds.add(item.getGroupId());
                labelPojo.setGroupId(item.getGroupId());
                labelPojos.add(labelPojo);
            });
            // 回收站需要返回分组名称
            if (Objects.equals(BasicConstant.ONE, labelListDTO.getEnable())) {
                param.clear();
                param.put("corpid", corpid);
                param.put("formId", labelListDTO.getFormId());
                param.put("appId", labelListDTO.getAppId());
                param.put("del", DelEnum.NORMAL.getDel());
                List<LabelGroupEntity> entitys = labelGroupModel.findEntitys(param);
                Map<Long, String> idToName = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                entitys.forEach(item -> idToName.put(item.getId(), item.getGroupName()));
                labelPojos.forEach(item -> {
                    item.setGroupName(idToName.get(labelIdToGroupId.get(item.getId())));
                });
            }
        }
        LabelListVO labelListVO = new LabelListVO();

        labelListVO.setLabelListVO(labelPojos);
        return labelListVO;
    }

    /**
     * 详情页更新个人以及企业标签
     * @param detailLabelUpdateDTO
     * @return
     * @throws XbbException
     */
    @Override
    public FormDataUpdateBatchVO updateDetailLabel(DetailLabelUpdateDTO detailLabelUpdateDTO)  throws XbbException {
        try {
            FormDataUpdateBatchVO formDataUpdateBatchVO = new FormDataUpdateBatchVO();
            FormDataUpdateBatchDTO formDataUpdateBatchDTO = detailLabelUpdateDTO.getFormDataUpdateBatchDTO();
            if(Objects.nonNull(formDataUpdateBatchDTO)){
                BeanUtils.copyProperties(detailLabelUpdateDTO, formDataUpdateBatchDTO);
                formDataUpdateBatchDTO.setIsRecordDynamic(0);
                formDataUpdateBatchDTO.setIsBatch(2);
                //走之前老的逻辑更新企业标签
                formDataUpdateBatchVO = listBatchService.updateBatch(formDataUpdateBatchDTO);
            }
            //更新个人标签
            PersonLabelSaveDTO personLabelSaveDTO = detailLabelUpdateDTO.getPersonLabelSaveDTO();
            if(Objects.nonNull(personLabelSaveDTO)){
                BeanUtils.copyProperties(detailLabelUpdateDTO, personLabelSaveDTO);
                if (Objects.nonNull(personLabelSaveDTO) && personLabelSaveDTO.getLabelNameList() !=null) {
                    personLabelService.updateLabelName(personLabelSaveDTO);
                }
            }
            return formDataUpdateBatchVO;
        } catch (XbbException e){
            throw e;
        }catch (Exception e) {
            LOG.error("详情页新建/修改标签失败" + e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, ErrorMessageConstant.SAVE_ERROR);
        }
    }

    @Override
    public SearchDataInConditionVO getConditionLabel(SearchDataInConditionDTO searchDataInConditionDTO) throws XbbException {
        SearchDataInConditionVO searchDataInConditionVO = new SearchDataInConditionVO();
        try {
            if(Objects.equals(searchDataInConditionDTO.getBusinessType(),XbbRefTypeEnum.CONTRACT_PERFORMANCE.getCode()) || Objects.equals(searchDataInConditionDTO.getBusinessType(),XbbRefTypeEnum.CONTRACT_PRODUCT.getCode())){
                return searchDataInConditionVO;
            }
            PaasFormEntity paasFormEntity = new PaasFormEntity();
            // 无用
//            saasListHelp.packageSearchDataCondition(searchDataInConditionDTO);
            if (Objects.equals(searchDataInConditionDTO.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
                //工单
                WorkOrderFormEntity workOrderFormEntity = workOrderFormModel.getByKey(searchDataInConditionDTO.getFormId(), searchDataInConditionDTO.getCorpid());
                BeanUtil.copyProperties(workOrderFormEntity, paasFormEntity);
            } else {
                paasFormEntity = paasFormModel.getByFormId(searchDataInConditionDTO.getFormId(),searchDataInConditionDTO.getCorpid());
            }

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", searchDataInConditionDTO.getCorpid());
            param.put("formId", searchDataInConditionDTO.getFormId());
            if (StringUtil.isNotEmpty(String.valueOf(searchDataInConditionDTO.getValue()))) {
                param.put("nameLike", searchDataInConditionDTO.getValue());
            }
            param.put("appId", paasFormEntity.getAppId());
            param.put("del", DelEnum.NORMAL.getDel());
            if (Objects.equals(searchDataInConditionDTO.getPlatform(), PlatFormEnum.DINGTALK.getValue())) {
                param.put("start", 0);
                param.put("pageNum", 10);
            }
            List<LabelEntity> entitys = labelModel.findEntitys(param);
            Map<String, Object> groupParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            groupParam.put("corpid", searchDataInConditionDTO.getCorpid());
            groupParam.put("formId", searchDataInConditionDTO.getFormId());
            groupParam.put("del", DelEnum.NORMAL.getDel());
            List<LabelGroupEntity> labelGroupEntity = labelGroupModel.findEntitys(groupParam);
            List<ItemDataPoJo> labelGroupItems = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(labelGroupEntity)) {
                ItemDataPoJo itemDataPoJo;
                for (LabelGroupEntity groupEntity : labelGroupEntity) {
                    itemDataPoJo = new ItemDataPoJo();
                    itemDataPoJo.setText(groupEntity.getGroupName());
                    itemDataPoJo.setValue(groupEntity.getId());
                    if (CollectionUtils.isNotEmpty(entitys)){
                        List<LabelEntity> labelEntityList = entitys.stream().filter(entity -> (Objects.equals(groupEntity.getId(), entity.getGroupId()) && Objects.equals(BasicConstant.ZERO, entity.getEnable()))).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(labelEntityList)) {
                            List<ItemDataPoJo> labelItems = new ArrayList<>();
                            for (LabelEntity labelEntity : labelEntityList) {
                                ItemDataPoJo label =new ItemDataPoJo();
                                label.setText(labelEntity.getName());
                                label.setValue(labelEntity.getId());
                                labelItems.add(label);
                            }
                            itemDataPoJo.setItemDataPoJoList(labelItems);
                            labelGroupItems.add(itemDataPoJo);
                        }
                    }
                }
                //回收站分组
                List<LabelEntity> labelEntityList = entitys.stream().filter(entity -> Objects.equals(BasicConstant.ONE, entity.getEnable())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(labelEntityList)) {
                    List<ItemDataPoJo> labelItems = new ArrayList<>();
                    for (LabelEntity labelEntity : labelEntityList) {
                        ItemDataPoJo label =new ItemDataPoJo();
                        label.setText(labelEntity.getName());
                        label.setValue(labelEntity.getId());
                        labelItems.add(label);
                    }
                    itemDataPoJo = new ItemDataPoJo();
                    itemDataPoJo.setText("回收站");
                    itemDataPoJo.setValue("-1");
                    itemDataPoJo.setItemDataPoJoList(labelItems);
                    labelGroupItems.add(itemDataPoJo);
                }
            }
            searchDataInConditionVO.setItems(labelGroupItems);
        } catch (Exception e) {
            LOG.error("labelService.getConditionLabel 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return searchDataInConditionVO;
    }

    /**
     * 创建默认标签
     * @param labelListDTO
     * @return
     * @throws XbbException
     */
    public LabelEntity createDefaultLabel(LabelListDTO labelListDTO) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", labelListDTO.getCorpid());
        param.put("formId", labelListDTO.getFormId());
        Integer count = labelModel.getEntitysCount(param);
        LabelEntity labelEntity = null;
        if (Objects.equals(count, BasicConstant.ZERO)){
            labelEntity = new LabelEntity();
            labelEntity.setCorpid(labelListDTO.getCorpid());
            labelEntity.setAppId(labelListDTO.getAppId());
            labelEntity.setFormId(labelListDTO.getFormId());
            labelEntity.setBusinessType(getBusinessType(labelListDTO.getCorpid(), labelListDTO.getAppId(), labelListDTO.getFormId()));
            labelEntity.setName(I18nMessageUtil.getMessage(PaasConstant.DEFAULT_LABEL_NAME));
            labelEntity.setColor(I18nMessageUtil.getMessage(PaasConstant.DEFAULT_LABEL_COLOR));
            labelEntity.setSort(BasicConstant.ZERO);
            labelEntity.setEnable(BasicConstant.ZERO);
            labelEntity.setCreatorId(labelListDTO.getUserId());
            labelEntity.setGroupId(labelListDTO.getGroupId());
            try {
                labelModel.insert(labelEntity);
            } catch (XbbException e) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }
        return labelEntity;
    }

    private  Integer getBusinessType(String corpid, Long appId, Long formId) {
        Integer businessType = 0;
        PaasAppEntity appEntity = paasAppModel.getByKey(appId, corpid);
        if (Objects.equals(appEntity.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())){
            businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        } else{
            PaasFormEntityExt formEntityExt = paasFormModel.getByKey(formId, corpid);
            businessType = formEntityExt.getBusinessType();
        }
        return businessType;
    }

    @Override
    public LabelShowVO getAllLabelList(LabelListDTO labelListDTO) throws XbbException {
        Long appId = labelListDTO.getAppId();
        Long formId = labelListDTO.getFormId();
        String corpid = labelListDTO.getCorpid();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 客户关联跟进记录如果设置了标签，特殊处理一下
        if (Objects.equals(labelListDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode()) || Objects.equals(labelListDTO.getBusinessType(), XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode())){
            // 重现查一遍
            PaasFormEntityExt byBusinessType = paasFormModel.getByBusinessType(labelListDTO.getBusinessType(), labelListDTO.getCorpid());
            if (Objects.nonNull(byBusinessType)){
                formId = byBusinessType.getId();
                appId = byBusinessType.getAppId();
            }
        }
        List<Long> labelIds = labelListDTO.getLabelIds();
        if (CollectionsUtil.isEmpty(labelIds)){
            labelIds = new ArrayList<>();
        }
        List<LabelEntity> labelEntities= new ArrayList<>();
        param.put("corpid", corpid);
        param.put("formId", formId);
        param.put("appId", appId);
        param.put("orderByStr", " sort desc " );
        // 这儿就不添加del条件了
        List<LabelGroupEntity> groupEntities = labelGroupModel.findEntitys(param);
        if (CollectionsUtil.isNotEmpty(groupEntities)){

            param.clear();
            param.put("corpid", corpid);
            param.put("formId", formId);
            param.put("appId", appId);
            if (StringUtil.isNotEmpty(labelListDTO.getNameLike())) {
                param.put("nameLike", labelListDTO.getNameLike());
            }
            param.put("orderByStr", " group_id desc , sort asc " );
            param.put("del", DelEnum.NORMAL.getDel());
            labelEntities = labelModel.findEntitys(param);
        } else {
            createDefaultLabelData(labelListDTO, appId, formId, corpid, labelEntities, groupEntities);
        }
        List<GroupLabelTreePojo> groupLabelTreePojos = new ArrayList<>();
        for (LabelGroupEntity groupEntity : groupEntities) {
            if (Objects.equals(groupEntity.getDel(), DelEnum.DELETE.getDel())){
                continue;
            }
            GroupLabelTreePojo groupLabelTreePojo = new GroupLabelTreePojo();
            groupLabelTreePojo.setId(groupEntity.getId());
            groupLabelTreePojo.setLabelGroupName(groupEntity.getGroupName());
            List<LabelEntity> subLabelTree = getSubLabelTree(groupEntity.getId(), labelEntities, labelIds, labelListDTO.getIsReLabel());
            if (CollectionsUtil.isEmpty(subLabelTree)){
                continue;
            }
            groupLabelTreePojo.setLabelEntities(subLabelTree);
            groupLabelTreePojos.add(groupLabelTreePojo);
        }
        LabelShowVO labelShowVO = new LabelShowVO();
        labelShowVO.setLabelTreePojos(groupLabelTreePojos);
        return labelShowVO;
    }

    @Override
    public AllLabelShowVO getPersonLabelList(LabelListDTO labelListDTO) throws XbbException {
        Long appId = labelListDTO.getAppId();
        Long formId = labelListDTO.getFormId();
        String corpid = labelListDTO.getCorpid();
        String userId = labelListDTO.getUserId();
        Integer refType = labelListDTO.getBusinessType();
        Integer refId = labelListDTO.getRefId();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 客户关联跟进记录如果设置了标签，特殊处理一下
        if (Objects.equals(labelListDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode()) || Objects.equals(labelListDTO.getBusinessType(), XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode())){
            // 重现查一遍
            PaasFormEntityExt byBusinessType = paasFormModel.getByBusinessType(labelListDTO.getBusinessType(), labelListDTO.getCorpid());
            if (Objects.nonNull(byBusinessType)){
                formId = byBusinessType.getId();
                appId = byBusinessType.getAppId();
            }
        }
        List<Long> labelIds = labelListDTO.getLabelIds();
        if (CollectionsUtil.isEmpty(labelIds)){
            labelIds = new ArrayList<>();
        }
        List<LabelEntity> labelEntities= new ArrayList<>();
        param.put("corpid", corpid);
        param.put("formId", formId);
        param.put("appId", appId);
        param.put("orderByStr", " sort desc " );
        // 这儿就不添加del条件了
        List<LabelGroupEntity> groupEntities = labelGroupModel.findEntitys(param);
        if (CollectionsUtil.isNotEmpty(groupEntities)){

            param.clear();
            param.put("corpid", corpid);
            param.put("formId", formId);
            param.put("appId", appId);
            if (StringUtil.isNotEmpty(labelListDTO.getNameLike())) {
                param.put("nameLike", labelListDTO.getNameLike());
            }
            param.put("orderByStr", " group_id desc , sort asc " );
            param.put("del", DelEnum.NORMAL.getDel());
            labelEntities = labelModel.findEntitys(param);
        } else {
            createDefaultLabelData(labelListDTO, appId, formId, corpid, labelEntities, groupEntities);
        }
        List<GroupLabelTreePojo> groupLabelTreePojos = new ArrayList<>();
        for (LabelGroupEntity groupEntity : groupEntities) {
            if (Objects.equals(groupEntity.getDel(), DelEnum.DELETE.getDel())){
                continue;
            }
            GroupLabelTreePojo groupLabelTreePojo = new GroupLabelTreePojo();
            groupLabelTreePojo.setId(groupEntity.getId());
            groupLabelTreePojo.setLabelGroupName(groupEntity.getGroupName());
            List<LabelEntity> subLabelTree = getSubLabelTree(groupEntity.getId(), labelEntities, labelIds, labelListDTO.getIsReLabel());
            if (CollectionsUtil.isEmpty(subLabelTree)){
                continue;
            }
            groupLabelTreePojo.setLabelEntities(subLabelTree);
            groupLabelTreePojos.add(groupLabelTreePojo);
        }

        //查询个人标签
        PersonLabelEntity personLabelEntity = new PersonLabelEntity();
        if (Objects.nonNull(refId)) {
            param.clear();
            param.put("corpid", corpid);
            param.put("refType", refType);
            param.put("refId", refId);
            param.put("ownerId", userId);
            personLabelEntity = personLabelModel.getByParamColumns(param);
        }
        AllLabelShowVO allLabelShowVO = new AllLabelShowVO();
        allLabelShowVO.setLabelTreePojos(groupLabelTreePojos);
        allLabelShowVO.setPersonLabelEntity(personLabelEntity);
        return allLabelShowVO;
    }

    /**
     * 创建默认标签,默认分组
     * @param labelListDTO
     * @param appId
     * @param formId
     * @param corpid
     * @param labelEntities
     * @param groupEntities
     * @throws XbbException
     */
    public void createDefaultLabelData(LabelListDTO labelListDTO, Long appId, Long formId, String corpid, List<LabelEntity> labelEntities, List<LabelGroupEntity> groupEntities) throws XbbException {
        // 添加默认分组,默认标签
        String userId = labelListDTO.getUserId();
        LabelGroupEntity defaultLabelGroup = labelGroupService.createDefaultLabelGroup(userId, corpid, appId, formId);
        LabelListDTO labelListDTO1 = new LabelListDTO();
        BeanUtil.copyProperties(labelListDTO, labelListDTO1);
        labelListDTO1.setGroupId(defaultLabelGroup.getId());
        LabelEntity defaultLabel = createDefaultLabel(labelListDTO1);
        groupEntities.add(defaultLabelGroup);
        if (Objects.nonNull(defaultLabel)) {
            labelEntities.add(defaultLabel);
        }
    }

    private List<LabelEntity> getSubLabelTree(Long id, List<LabelEntity> labelEntities, List<Long> labelIds, Integer isReLabel) {
        List<LabelEntity> labelList = new ArrayList<>();
        List<Long> labelId = new ArrayList<>();
        for (LabelEntity item : labelEntities) {
            if ((Objects.equals(item.getEnable(), BasicConstant.ONE) && !Objects.equals(isReLabel, BasicConstant.ONE) )&& !labelIds.contains(item.getId())) {
                continue;
            }
            if (Objects.equals(item.getGroupId(), id)) {
                labelList.add(item);
                labelId.add(item.getId());
            }
        }
        return labelList;
    }

    @Override
    public LabelSaveVO saveLabel(LabelSaveDTO labelSaveDTO) throws XbbException {
        String corpid = labelSaveDTO.getCorpid();
        Long appId = labelSaveDTO.getAppId();
        Long formId = labelSaveDTO.getFormId();
        String name = labelSaveDTO.getName();
        String loginUserName = labelSaveDTO.getLoginUserName();
        Long groupId = labelSaveDTO.getGroupId();
        Long id = labelSaveDTO.getId();
        String userId = labelSaveDTO.getLoginUser().getUserId();
        if (Objects.equals(labelSaveDTO.getId(), 0L) && name.contains(",")){
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120011);
        }
        LabelRepeatDTO labelRepeatDTO = new LabelRepeatDTO();
        BeanUtil.copyProperties(labelSaveDTO, labelRepeatDTO);
        Integer repeat = repeatForSave(labelRepeatDTO).getIsRepeat();
        if (Objects.equals(repeat, BasicConstant.ONE)) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120004);
        }
        Integer sort = null;
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("groupId", groupId);
        if (Objects.equals(labelSaveDTO.getId(), 0L)) {
            // 标签排序
            sort = labelModel.getEntitysCount(param);
        } else {
            //排除回收站中的标签
            param.put("enable", BasicConstant.ZERO);
        }

        param.put("del", DelEnum.NORMAL.getDel());
        Integer count = labelModel.getEntitysCount(param);
        // 数量限制
        if (count >= PaasConstant.LIMIT_MAX_NUM_LABEL) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120012);
        }
        // 名称判断
        // param.put("name", labelSaveDTO.getName());
        // count = labelModel.getEntitysCount(param);
        // if (count > 0 ){
        //     throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        // }
        // 插入实体
        LabelEntity labelEntity = new LabelEntity();
        boolean isNew = false;
        String oldName = "";
        JSONObject oldObj = null;
        if (id <= 0) {
            labelEntity.setCorpid(corpid);
            labelEntity.setCreatorId(labelSaveDTO.getLoginUser().getUserId());
            labelEntity.setDel(0);
            labelEntity.setEnable(0);
            labelEntity.setColor(labelSaveDTO.getColor());
            labelEntity.setFormId(formId);
            labelEntity.setAppId(appId);
            labelEntity.setSort(sort);
            labelEntity.setBusinessType(labelSaveDTO.getBusinessType());
            labelEntity.setGroupId(labelSaveDTO.getGroupId());
            labelEntity.setName(name);
            labelEntity.setAppId(labelSaveDTO.getAppId());
            isNew = true;
        } else {
            labelEntity = labelModel.getByKey(id, corpid);
            if (Objects.isNull(labelEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
            }
            oldName = labelEntity.getName();
            oldObj = JSONObject.parseObject(JSONObject.toJSONString(labelEntity));
            labelEntity.setGroupId(labelSaveDTO.getGroupId());
            labelEntity.setName(name);
            labelEntity.setEnable(0);
            labelEntity.setColor(labelSaveDTO.getColor());
        }
        Integer save;
        try {
            save = labelModel.save(labelEntity);
        } catch (Exception e) {
            LOG.error("新建/修改标签失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        LabelSaveVO labelSaveVO = new LabelSaveVO();
        labelSaveVO.setId(labelEntity.getId());

        String memo;
        OperateTypeEnum operateTypeEnum;
        if (isNew) {
            operateTypeEnum = OperateTypeEnum.NEW;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_ADD), loginUserName, name);
        } else {
            operateTypeEnum = OperateTypeEnum.EDIT;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_UPDATE), loginUserName, name, oldName, name);
        }
        mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.LABEL_SET, operateTypeEnum, id.toString(), name, memo, labelSaveDTO.getHttpHeader());
        return labelSaveVO;
    }

    private LabelRepeatVO repeatForSave(LabelRepeatDTO labelRepeatDTO) {
        Long id = labelRepeatDTO.getId();
        Long appId = labelRepeatDTO.getAppId();
        String name = labelRepeatDTO.getName();
        List<String> nameIn = new ArrayList<>();
        nameIn.add(name);
        Long groupId = labelRepeatDTO.getGroupId();
        Long formId = labelRepeatDTO.getFormId();
        LabelRepeatVO labelRepeatVO = new LabelRepeatVO();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("appId", appId);
        param.put("nameIn", nameIn);
        param.put("groupId", groupId);
        param.put("formId", formId);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("negId",id);
        List<LabelEntity> entitys = labelModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(entitys)) {
            labelRepeatVO.setIsRepeat(BasicConstant.THREE);
            return labelRepeatVO;
        }
        for (LabelEntity entity : entitys) {
            if (Objects.equals(entity.getGroupId(), groupId)) {
                labelRepeatVO.setIsRepeat(BasicConstant.ONE);
                break;
            }
        }
        return labelRepeatVO;
    }

    @Override
    public LabelDeleteVO deleteLabel(LabelDeleteDTO labelDeleteDTO) throws XbbException {
        List<Long> labelIds = labelDeleteDTO.getIds();
        String corpid = labelDeleteDTO.getCorpid();
        // 查询是否有改id
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", labelIds);
        param.put("corpid", labelDeleteDTO.getCorpid());
        List<LabelEntity> entitys = labelModel.findEntitys(param);
        if (!Objects.equals(entitys.size(), labelIds.size())) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120019);
        }
        checkDefaulteValue(labelIds, corpid, entitys);
        long now = DateTimeUtil.getInt();
        entitys.forEach(item -> {
            item.setEnable(BasicConstant.ONE);
            item.setUpdateTime(now);
        });
        try {
            Integer update = labelModel.updateBatch(entitys, corpid);
        } catch (Exception e) {
            LOG.error("删除标签失败" + labelIds);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        LabelDeleteVO labelDeleteVO = new LabelDeleteVO();
        labelDeleteVO.setIds(labelIds);


        // 记录日志
        String userName = labelDeleteDTO.getLoginUserName();
        StringBuilder name = new StringBuilder();
        StringBuilder ids = new StringBuilder();
        entitys.forEach(item -> {
            name.append(item.getName()).append("-");
            ids.append(item.getId()).append("-");
        });
        String nameStr = null;
        String idsStr = null;
        if ( Objects.nonNull(name) && Objects.nonNull(ids)) {
            nameStr = name.substring(0,name.length()-1);
            idsStr = ids.substring(0,ids.length()-1);
        }

        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_DELETE), userName, nameStr);
        mongoLogHelp.buildLog(corpid, labelDeleteDTO.getUserId(), userName, OperateModuleTypeEnum.LABEL_SET, OperateTypeEnum.DELETE, idsStr, nameStr, memo, labelDeleteDTO.getHttpHeader());

        return labelDeleteVO;
    }

    private void checkDefaulteValue(List<Long> labelIds, String corpid, List<LabelEntity> labelEntities) throws XbbException {
        Map<Long, String> id2Name = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        labelEntities.forEach(item->{
            id2Name.put(item.getId(), item.getName());
        });
        Integer businessType = labelEntities.get(0).getBusinessType();
        List<FieldAttrEntity> fieldAttrEntities = new ArrayList<>();
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())){
            WorkOrderExplainEntityExt workOrderExplainEntityExt = workOrderExplainModel.getByFormId(labelEntities.get(0).getFormId(), corpid);
            fieldAttrEntities = JSONArray.parseArray(workOrderExplainEntityExt.getExplains(), FieldAttrEntity.class);
        } else {
            PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(labelEntities.get(0).getFormId(), corpid);
            fieldAttrEntities = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        }
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        for (FieldAttrEntity item : fieldAttrEntities) {
            if (Objects.equals(item.getFieldType(), FieldTypeEnum.LABEL.getType())) {
                fieldAttrEntity= item;
                break;
            }
        }
        List<Long> defaultLabelIds = new ArrayList<>();
        DefaultAttrPoJo defaultAttr = fieldAttrEntity.getDefaultAttr();
        if (Objects.nonNull(defaultAttr.getDefaultValue())) {
            Object defaultValue1 = defaultAttr.getDefaultValue();
            if (defaultValue1 instanceof JSONArray){
                JSONArray defaultValue = (JSONArray) defaultValue1;
                for (Object o : defaultValue) {
                    if (o instanceof JSONObject){
                        JSONObject jsonObject = (JSONObject)o;
                        defaultLabelIds.add(jsonObject.getLong("id"));
                    } else {
                        defaultLabelIds.add(Long.parseLong(o.toString()));
                    }
                }
            }
        }
        StringBuilder stringBuilder = new StringBuilder();

        defaultLabelIds.retainAll(labelIds);
        defaultLabelIds.forEach(item->{
            stringBuilder.append(id2Name.get(item)).append("  ");
        });
        if (defaultLabelIds.size() > 0) {
            LOG.error("标签被设置为默认值,不能删除");
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120016, String.format(SystemLabelErrorCodeEnum.API_ERROR_1120016.getMsg(), stringBuilder.toString()));
        }
    }

    @Override
    public LabelSortVO sortLabel(LabelSortDTO labelSortDTO) throws XbbException {
        List<LabelSortPojo> sortArray = labelSortDTO.getSortArray();
        Map<Long, Long> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> idIn = new ArrayList<>();
        for (LabelSortPojo pojo : sortArray) {
            Long id = pojo.getId();
            Long sort = pojo.getSort();
            sortMap.put(id, sort);
            idIn.add(id);
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", idIn);
        param.put("corpid", labelSortDTO.getCorpid());
        param.put("del", 0);
        try {
            labelModel.sortCategory(param, sortMap);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }

        LabelSortVO labelSortVO = new LabelSortVO();
        labelSortVO.setIds(idIn);

        return labelSortVO;
    }

    @Override
    public LabelRepeatVO repeat(LabelRepeatDTO labelRepeatDTO) throws XbbException {
        Long id = labelRepeatDTO.getId();
        Long appId = labelRepeatDTO.getAppId();
        String name = labelRepeatDTO.getName();
        Long groupId = labelRepeatDTO.getGroupId();
        Long formId = labelRepeatDTO.getFormId();
        LabelRepeatVO labelRepeatVO = new LabelRepeatVO();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("appId", appId);
        param.put("name", name);
        param.put("formId", formId);
        param.put("groupId", groupId);
        // param.put("enabel", 0);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("negId",id);
        List<LabelEntity> entitys = labelModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(entitys)) {
            labelRepeatVO.setIsRepeat(BasicConstant.THREE);
            return labelRepeatVO;
        }
        for (LabelEntity entity : entitys) {
            if (Objects.equals(entity.getGroupId(), groupId)) {
                labelRepeatVO.setIsRepeat(BasicConstant.ONE);
                break;
            }
        }
        return labelRepeatVO;
    }


    @Override
    public LabelTotalDeleteVO deleteTotal(LabelTotalDeleteDTO labelTotalDeleteDTO) throws XbbException {
        Long labelId = labelTotalDeleteDTO.getLabelId();
        Long appId = labelTotalDeleteDTO.getAppId();
        String corpid = labelTotalDeleteDTO.getCorpid();
        Long formId = labelTotalDeleteDTO.getFormId();
        LabelEntity labelEntity = labelModel.getByKey(labelId, corpid);
        PaasFormExplainEntity explainEntity = new PaasFormExplainEntity();
        if (Objects.equals(labelEntity.getBusinessType(), XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt byFormId = workOrderExplainModel.getByFormId(formId, corpid);
            BeanUtil.copyProperties(byFormId, explainEntity);
        } else {
           explainEntity =paasFormExplainModel.getByFormId(formId, corpid);
        }
        String attr = getExplainForLable(labelId, explainEntity);
        Integer businessType = explainEntity.getBusinessType();
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, explainEntity.getBusinessType(), explainEntity.getSaasMark());
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery("formId", formId));
        String attr2 = StringConstant.JSON_DATA + StringConstant.POINT + attr;
        boolQueryBuilder.filter(existsQuery(attr2));
        boolQueryBuilder.filter(boolQuery().should(termsQuery(attr2, Arrays.asList(labelId))));
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(indexTypeEnum.getIndex()).types(indexTypeEnum.getType());
        searchRequest.source(sourceBuilder);
        long count = xbbElasticsearchRestTemplate.count(searchRequest, PaasFormDataEntityExt.class);
        // 校验审批中的数据中是否有使用该标签
        if (count > 0) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(MessageConstant.CAN_NOT_REMOVE_LABEL));
        }
        //第一次编辑表单拖动标签时，表单解释里面是没有标签的，attr是空的
        List<PaasProcessDataEntity> inApprovalDataByIdConditionJsonArray = StringUtil.isEmpty(attr) ? null : paasProcessDataModel.getInApprovalDataByIdConditionJsonArray(businessType, attr, Arrays.asList(labelId), corpid, Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
        if (CollectionsUtil.isNotEmpty(inApprovalDataByIdConditionJsonArray)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.HAS_PROCESS_DATA);
        }

        try {
            Integer integer = labelModel.deleteBykey(labelId, corpid);
        } catch (Exception e) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        LabelTotalDeleteVO labelTotalDeleteVO = new LabelTotalDeleteVO();
        labelTotalDeleteVO.setLabelId(labelId);

        // 记录日志
        String userName = labelTotalDeleteDTO.getLoginUserName();
        String name = labelEntity.getName();
        Long id = labelEntity.getId();


        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_WORK_ORDER_DELETE), userName, name);
        mongoLogHelp.buildLog(corpid, labelTotalDeleteDTO.getUserId(), userName, OperateModuleTypeEnum.LABEL_SET, OperateTypeEnum.DELETE, id.toString(), name.toString(), memo, labelTotalDeleteDTO.getHttpHeader());

        return labelTotalDeleteVO;
    }

    public String getExplainForLable(Long labelId, PaasFormExplainEntity explainEntity) throws XbbException {
        List<FieldAttrEntity> fieldList = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        String attr = "";
        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
        for (FieldAttrEntity item : fieldList) {
            if (Objects.equals(item.getFieldType(), FieldTypeEnum.LABEL.getType())) {
                fieldAttrEntity= item;
                attr = item.getAttr();
                break;
            }
        }
        DefaultAttrPoJo defaultAttr = fieldAttrEntity.getDefaultAttr();
        if (Objects.nonNull(defaultAttr.getDefaultValue())) {
            Object defaultValue1 = defaultAttr.getDefaultValue();
            if (defaultValue1 instanceof JSONArray){
                JSONArray defaultValue = (JSONArray) defaultValue1;
                for (Object o : defaultValue) {
                    if (o instanceof JSONObject){
                        JSONObject jsonObject = (JSONObject)o;
                        if (Objects.equals(jsonObject.getLong("id"), labelId)){
                            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120014);
                        }
                    } else {
                        if (Objects.equals(Long.parseLong(o.toString()), labelId)){
                            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120014);
                        }
                    }
                }
            }
        }
        return attr;
    }
}
